﻿using System;
using System.Collections.Generic;
using System.Linq;
using OfficeOpenXml;
using System.IO;
using Citi.ResourceConsolidation.Domain;
using Citi.RoutineBase;
using System.Configuration;
using System.Timers;
using Citi.Import.Util;
using Citi.GocAttributes.Domain;
using Citi.Helpers;

namespace Citi.ResourceConsolidation.SchedulerUI.GDW
{
    public class GDWReport : IExecutableRoutine
    {
        public IEnumerable<RoutineParameter> Parameters { get { return null; } }
        private string GocConnectionString = ConfigurationManager.ConnectionStrings["GocAttributesEntities"].ConnectionString;

        public void Rollback(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }

        private List<JobTitle> JobTitles
        {
            get
            {
                return CacheFacade.Get(() => new JobTitle().SelectAll<JobTitle>()).ToList();
            }
        }

        private List<Resource> Resources
        {
            get
            {
                return CacheFacade.Get(() => new Resource().SelectAll<Resource>()).ToList();
            }
        }

        private static Timer timer = new Timer { Interval = 120000 };
        private static ICurrentAction action;

        private static void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            action.Description = "Generating report";
        }

        private static void StartTimer(ref ICurrentAction currentAction)
        {
            timer.Elapsed += TimerOnElapsed;
            action = currentAction;

            timer.Start();
        }

        private static void StopTimer()
        {
            timer.Stop();
        }

        public void Start(DateTime scheduledDate, ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            //var businessDay = GetLastBusinessDay(DateTime.Now.Date.Year, DateTime.Now.Date.Month);

            var robotUsername = parameters["RobotUsername"].ToString();
            var robotPassword = parameters["RobotPassword"].ToString();

            //using (NetworkShareAccesser.Access(@"\\gruvnascti0016.wlb.lac.nsroot.net\DATA_GRP1\FTOOLS\Apps\GDWAutomation\Template\", robotUsername, robotPassword))
            //{
            //using (NetworkShareAccesser.Access(@"\\gruvnascti0016.wlb.lac.nsroot.net", robotUsername, robotPassword))
            //{
                StartTimer(ref currentAction);
                GenerateGDWReport(DateTime.Today, ref currentAction, robotUsername, robotPassword);
                StopTimer();
            //}

            //}
        }

        public void Stop(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            throw new NotImplementedException();
        }

        private void GenerateGDWReport(DateTime referenceDate, ref ICurrentAction currentAction, string robotUsername, string robotPassword)
        {
            //referenceDate = Convert.ToDateTime("14/03/2014 00:00:00");
            
            var gdwModel = new ResourceMonth().GetByReferenceDate(referenceDate).ToList();

            var template = @"\\gruvnascti0016.wlb.lac.nsroot.net\DATA_GRP1\FTOOLS\Apps\GDWAutomation\Template\GDWTemplate.xlsx";

            var fileName = string.Concat("GDW_", DateTime.Now.ToString("yyyyMMdd"), ".xlsx");
            var outputFile = @"\\gruvnascti0009.wlb.lac.nsroot.net\DATA_GRP1\FPCRelat\GDW\";
            var tempFile = Path.Combine(@"C:\Temp\", fileName);
            var destinationFile = Path.Combine(outputFile, fileName);

            currentAction.Description = string.Format("Copying file to {0}", tempFile);

            using (NetworkShareAccesser.Access(template, robotUsername, robotPassword))
            {
                if (System.IO.File.Exists(tempFile))
                {
                    File.SetAttributes(tempFile, FileAttributes.Normal);
                    System.IO.File.Delete(tempFile);
                }

                System.IO.File.Copy(template, tempFile, true);
                currentAction.Description = "File copied to Temp Folder";
            }

            using (var excelPackage = new ExcelPackage(new FileInfo(tempFile)))
            {
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];

                int row = 2;

                currentAction.Description = string.Format("Started to write excel. Total lines: {0}", gdwModel.Count);

                foreach (var item in gdwModel)
                {
                    if (gdwModel.IndexOf(item) > 0 && gdwModel.IndexOf(item) % 500 == 0)
                        currentAction.Description = string.Format("Total written lines:{0}", gdwModel.IndexOf(item));

                    worksheet.Cells[row, 1].Value = item.Resource.GeId;
                    worksheet.Cells[row, 2].Value = item.Resource.SoeId;
                    worksheet.Cells[row, 3].Value = item.Resource.FullName;
                    worksheet.Cells[row, 4].Value = item.GocAttributes;
                    worksheet.Cells[row, 5].Value = item.GocAttributes;
                    worksheet.Cells[row, 6].Value = item.Goc == null ? "-" : item.Goc.LongDescription;
                    worksheet.Cells[row, 7].Value = item.Goc == null ? "-" : item.Goc.GetRuleResult(DatabaseEnums.TypeResultType.OTFunctionL4);
                    worksheet.Cells[row, 8].Value = item.LocalCode;
                    worksheet.Cells[row, 9].Value = item.BusinessUnit.Code;
                    worksheet.Cells[row, 10].Value = item.BusinessUnit.Description;
                    worksheet.Cells[row, 11].Value = item.Operating.Code;
                    worksheet.Cells[row, 12].Value = item.Operating.Description;

                    worksheet.Cells[row, 13].Value = item.Goc == null ? "-" : item.Goc.ManagedSegment.Code.ToString();
                    worksheet.Cells[row, 14].Value = item.Goc == null ? "-" : item.Goc.ManagedSegment.Description.ToString();
                    worksheet.Cells[row, 15].Value = item.HumanResource.Code;
                    worksheet.Cells[row, 16].Value = item.HumanResource.Description;

                    var jobTitle = JobTitles.FirstOrDefault(x => x.Id == item.JobTitleId);
                    worksheet.Cells[row, 17].Value = jobTitle.Description;
                    worksheet.Cells[row, 18].Value = jobTitle.JobFamily.JobFunction.Description;
                    worksheet.Cells[row, 19].Value = jobTitle.Code;
                    worksheet.Cells[row, 20].Value = item.FMBDescription;
                    worksheet.Cells[row, 21].Value = jobTitle.JobFamily.Description;
                    worksheet.Cells[row, 22].Value = item.GlobalFunction;
                    worksheet.Cells[row, 23].Value = item.Resource.Active == "A" ? "Active" : item.Resource.Active == "T" ? "Terminated" : "Leave of Absence";
                    worksheet.Cells[row, 24].Value = item.EmployeeClass.Code;
                    worksheet.Cells[row, 25].Value = item.EmployeeClass.Description;
                    worksheet.Cells[row, 26].Value = item.FullOrPartTime;
                    worksheet.Cells[row, 27].Value = item.RegOrTemp;
                    worksheet.Cells[row, 28].Value = item.DirectFlag;

                    worksheet.Cells[row, 29].Value = item.DirectCount;
                    worksheet.Cells[row, 30].Value = item.FTE;
                    worksheet.Cells[row, 31].Value = item.FTEType;
                    worksheet.Cells[row, 32].Value = ((EmployeeClass.ClassDescription)item.FTEType).GetDescription();

                    worksheet.Cells[row, 33].Value = item.TotalHour;
                    worksheet.Cells[row, 34].Value = item.StandardHour;
                    worksheet.Cells[row, 35].Value = item.WorkingMonth;
                    worksheet.Cells[row, 36].Value = item.WorkingMonth;

                    worksheet.Cells[row, 37].Value = item.BusinessContact.Code;
                    worksheet.Cells[row, 38].Value = item.BusinessContact.Description;
                    worksheet.Cells[row, 39].Value = item.Vendor.Code;
                    worksheet.Cells[row, 40].Value = item.Vendor.Description;
                    worksheet.Cells[row, 41].Value = item.Currency;

                    worksheet.Cells[row, 42].Value = item.BillRate;
                    worksheet.Cells[row, 43].Value = item.Location.State;
                    worksheet.Cells[row, 44].Value = item.Location.Description;
                    worksheet.Cells[row, 46].Value = "-";
                    worksheet.Cells[row, 46].Value = item.Location.Country;
                    worksheet.Cells[row, 47].Value = item.Location.Region;

                    worksheet.Cells[row, 48].Value = "Brazil";
                    worksheet.Cells[row, 49].Value = "LATM";

                    worksheet.Cells[row, 50].Value = item.DomicileCountry.Description;
                    worksheet.Cells[row, 51].Value = item.ExpenseCode;
                    worksheet.Cells[row, 52].Value = "-";
                    worksheet.Cells[row, 53].Value = item.Goc == null ? "-" : item.Goc.LegalVehicle.Code;
                    worksheet.Cells[row, 54].Value = item.Goc == null ? "-" : item.Goc.LegalVehicle.Description;

                    worksheet.Cells[row, 55].Value = item.Officer.Code;
                    worksheet.Cells[row, 56].Value = item.Officer.Description;
                    worksheet.Cells[row, 57].Value = item.HrResponsibleGeId;

                    //var hrResponsibleName = new Resource().GetByGeid(item.HrResponsibleGeId);
                    var hrResponsibleName = gdwModel.Select(x=> x.Resource).FirstOrDefault(x=> x.GeId == item.HrResponsibleGeId);
                    worksheet.Cells[row, 58].Value = hrResponsibleName == null ? "-" : hrResponsibleName.FullName;

                    worksheet.Cells[row, 59].Value = item.Resource.GeId;

                    //var hrDirectManagerName = new Resource().GetByGeid(item.Resource.GeId);
                    var hrDirectManagerName = item.DirectManagerResource;
                    worksheet.Cells[row, 60].Value = hrDirectManagerName == null ? "-" : hrDirectManagerName.FullName;

                    if (item.Goc != null)
                    {
                        var managedSegment = item.Goc.ManagedSegment;
                        for (int i = managedSegment.TreeLevel; i >= 2; i--)
                        {
                            worksheet.Cells[row, 61 + (i * 2) - 4].Value = managedSegment.Code;
                            worksheet.Cells[row, 62 + (i * 2) - 4].Value = managedSegment.Description;

                            if (managedSegment.ParentId != null)
                                managedSegment = managedSegment.Parent;
                            else
                                break;
                        }

                        var humanResourceDept = item.HumanResourceDept;
                        for (int i = humanResourceDept.Level; i >= 2; i--)
                        {
                            worksheet.Cells[row, 81 + (i * 2) - 4].Value = humanResourceDept.Id;
                            worksheet.Cells[row, 82 + (i * 2) - 4].Value = humanResourceDept.Description;

                            if (humanResourceDept.ParentId != null)
                                humanResourceDept = humanResourceDept.Parent;
                            else
                                break;
                        }

                        var managedGeo = item.Goc.ManagedGeography;
                        for (int i = managedGeo.TreeLevel; i >= 2; i--)
                        {
                            worksheet.Cells[row, 97 + (i * 2) - 4].Value = managedGeo.Id;
                            worksheet.Cells[row, 98 + (i * 2) - 4].Value = managedGeo.Description;

                            if (managedGeo.ParentId != null)
                                managedGeo = managedGeo.Parent;
                            else
                                break;
                        }

                        var function = item.Goc.Function;
                        for (int i = function.TreeLevel; i >= 2; i--)
                        {
                            worksheet.Cells[row, 113 + (i * 2) - 4].Value = function.Code;
                            worksheet.Cells[row, 114 + (i * 2) - 4].Value = function.Description;

                            if (function.ParentId != null)
                                function = function.Parent;
                            else
                                break;
                        }
                    }

                    row++;
                }

                using (var range = worksheet.Cells[1, 1, row, 130])
                {
                    range.Style.Font.Size = 9;
                    range.Style.Font.Name = "Calibri";
                }

                excelPackage.Save();

                using (NetworkShareAccesser.Access(destinationFile, robotUsername, robotPassword))
                {
                    System.IO.File.Copy(tempFile, destinationFile, true);
                    currentAction.Description = "File copied";
                    File.SetAttributes(destinationFile, FileAttributes.Normal);
                }
            }
        }
    }
}
